library(tidyverse)
library(readr)
library(readxl)
library(janitor)
library(stringr)
library(scales)
library(lmtest)
library(sandwich)
library(broom)
library(tibble)
library(jsonlite)
library(forcats)
library(ggplot2)
library(ggrepel)
library(gganimate)
library(EEAaq)
library(gifski)
La fertilidad humana es sensible a condiciones ambientales que afectan tanto a la salud reproductiva como a las decisiones familiares.
En particular, la calidad del aire se ha relacionado con alteraciones hormonales, inflamación sistémica y estrés oxidativo que pueden reducir la fecundidad, aumentar el riesgo de pérdida gestacional y acortar la ventana fértil. Más allá de los mecanismos biológicos, el entorno en que las familias planifican también responde a expectativas de salud pública, seguridad ambiental y confianza institucional.
En este contexto, la vigilancia de la calidad del aire (monitorización sistemática, cobertura de estaciones, reporte y disponibilidad de datos) puede operar como un bien público que mejora la salud y reduce la incertidumbre sobre riesgos ambientales. Una red de vigilancia más densa y activa suele acompañar estrategias de control, cumplimiento normativo y comunicación del riesgo, y puede facilitar políticas de reducción de emisiones.
El resultado esperado (si estos canales funcionan) es un entorno más saludable y predecible para la crianza, lo que, en teoría, podría favorecer niveles más altos de fertilidad.
Sin embargo, a nivel agregado (país), se conoce menos acerca de:
El presente seminario aborda estas cuestiones desde una perspectiva descriptiva, utilizando datos agregados por país para Europa.
Analizar la vigilancia y medición de la calidad del aire en relación con la fertilidad media (TFR) en los países europeos.
Vigilancia vs fertilidad
¿Existe asociación entre la intensidad de la vigilancia de la calidad
del aire y la fertilidad media (TFR) de los países europeos?
NO₂ vs fertilidad
¿Están los niveles medios de NO₂ en los países europeos relacionados con
sus niveles medios de fertilidad (TFR)? Si es así, ¿de dónde proviene
dicho NO₂?
CO₂ vs fertilidad
¿Existe una relación directamente proporcional entre los niveles de
dióxido de carbono (CO₂) y la fertilidad?
PM₂.₅ en la vigilancia vs fertilidad
¿Se asocia la proporción de observaciones dedicadas a PM₂.₅ en los
sistemas de vigilancia de la calidad del aire de los países europeos con
su fertilidad media (TFR)?
Pregunta: ¿Existe una asociación entre la intensidad de vigilancia de la calidad del aire y la fertilidad en Europa?
Hipótesis inicial: Se espera que una mayor vigilancia del aire implique una mayor fertilidad. Por ello, esperamos que los países con más observaciones de calidad del aire tengan una TFR ligeramente superior, aunque esta relación no implica causalidad directa; es un test descriptivo de la asociación.
Si la hipótesis es consistente con los datos, esperamos observar una relación positiva entre el nivel de vigilancia (más observaciones) y la TFR.
Nota: La vigilancia se mide como el número de observaciones registradas por país y año en el sistema de AQ e-Reporting (EEA). La fertilidad se mide mediante la TFR media anual por país (Eurostat).
Trabajamos con dos fuentes principales de datos:
Calidad del aire: obtenida mediante
EEAaq::aq_annual_data() o CSV original
(DataExtract.csv)
Fertilidad: obtenida de Eurostat
(Fertilidad.csv) Se leen los archivos, se realiza una
limpieza inicial de columnas y se transforma el formato de los datos de
Eurostat (códigos geo) al formato de nombres de país homogéneos (pais)
para permitir la unión con los datos de vigilancia.
# 1. Lectura de datos y limpieza básica
aire <- read_delim(
"INPUT/DATA/DataExtract.csv",
delim = ",", escape_double = FALSE, trim_ws = TRUE
)
fertilidad <- read_delim(
"INPUT/DATA/Fertilidad.csv",
delim = ",", escape_double = FALSE, trim_ws = TRUE
)
aire <- aire %>% clean_names()
fertilidad <- fertilidad %>% clean_names()
# 2. Tabla de mapeo de códigos de país (Eurostat -> nombre)
mapa_paises_df <- tibble::tribble(
~geo, ~pais,
"AD", "Andorra",
"AL", "Albania",
"AM", "Armenia",
"AT", "Austria",
"AZ", "Azerbaijan",
"BA", "Bosnia and Herzegovina",
"BE", "Belgium",
"BG", "Bulgaria",
"BY", "Belarus",
"CH", "Switzerland",
"CY", "Cyprus",
"CZ", "Czechia",
"DE", "Germany",
"DK", "Denmark",
"EE", "Estonia",
"EL", "Greece",
"ES", "Spain",
"FI", "Finland",
"FR", "France",
"GE", "Georgia",
"GI", "Gibraltar",
"HR", "Croatia",
"HU", "Hungary",
"IE", "Ireland",
"IS", "Iceland",
"IT", "Italy",
"LI", "Liechtenstein",
"LT", "Lithuania",
"LU", "Luxembourg",
"LV", "Latvia",
"MC", "Monaco",
"MD", "Moldova",
"ME", "Montenegro",
"MK", "North Macedonia",
"MT", "Malta",
"NL", "Netherlands",
"NO", "Norway",
"PL", "Poland",
"PT", "Portugal",
"RO", "Romania",
"RS", "Serbia",
"RU", "Russia",
"SE", "Sweden",
"SI", "Slovenia",
"SK", "Slovakia",
"SM", "San Marino",
"TR", "Türkiye",
"UA", "Ukraine",
"UK", "United Kingdom",
"VA", "Vatican City",
"XK", "Kosovo"
# Agregados tipo "EU27_2020", etc. no se incluyen
)
Se preparan los datos para los análisis posteriores unificando los nombres de los países entre distintas fuentes, de manera que los datasets de fertilidad y calidad del aire sean comparables. Se realizan varias tareas:
Homogeneización de nombres de países: Se recodifican alias o variantes de nombres para asegurar consistencia entre datasets.
Resumen de fertilidad: Se calcula la TFR media y el número de años con datos disponibles para cada país.
Conteo de observaciones de aire: Se contabilizan las observaciones de PM2.5 por país y año, aplicando la homogeneización de nombres.
Unión de datos: Se combinan los resúmenes de fertilidad y de observaciones de aire por país, obteniendo un dataset base que servirá para posteriores normalizaciones y análisis.
Este paso es clave para que los análisis estadísticos posteriores puedan comparar correctamente la vigilancia de la calidad del aire con la fertilidad a nivel país, evitando inconsistencias debidas a diferencias de nombres o códigos de país.
# Homogeneizar alias de países
recode_pais <- function(x) {
x <- str_trim(x)
dplyr::recode(
x,
"Turkey" = "Türkiye",
"Czech Republic" = "Czechia",
"Russian Federation" = "Russia",
"Republic of Moldova" = "Moldova",
"UK" = "United Kingdom",
"Great Britain" = "United Kingdom",
.default = x
)
}
# Calcular la TFR media y número de años observados por país
resumir_fertilidad <- function(df) {
df %>%
group_by(pais) %>%
summarise(
n_anios = n(),
tfr_media = mean(tfr, na.rm = TRUE),
.groups = "drop"
) %>%
arrange(pais)
}
# Conteo de observaciones de aire por país-año y homogeneización de nombres
limpiar_y_contar_aire <- function(aire_raw) {
aire_raw %>%
mutate(
pais = str_trim(country),
anio = as.integer(year),
# Aplicar homogeneización
pais = recode_pais(country)) %>%
count(pais, anio, name = "n_obs_aire") %>%
arrange(pais, anio)
}
# Filtrar y transformar los datos de Eurostat de código a nombre de país
fert_codigos <- fertilidad %>%
filter(freq == "A") %>%
transmute(geo = geo, anio = as.integer(time_period), tfr = as.numeric(obs_value))
fert_paises <- fert_codigos %>%
left_join(mapa_paises_df, by = "geo") %>%
filter(!is.na(pais)) %>%
select(pais, anio, tfr)
# Resumen: TFR Media por país
fert_resumen_nombres <- resumir_fertilidad(fert_paises)
# Conteo de observaciones por país-año (Frecuencia de Vigilancia)
aire_conteo <- limpiar_y_contar_aire(aire)
# Resumen: Total de Observaciones por país (para normalización)
aire_resumen_pais <- aire_conteo %>%
group_by(pais) %>%
summarise(
total_obs_aire = sum(n_obs_aire, na.rm = TRUE),
.groups = "drop"
)
# Resumen base combinado (para posterior normalización)
resumen_aire_fert_pais <- aire_resumen_pais %>%
full_join(fert_resumen_nombres, by = "pais") %>%
arrange(pais)
Para obtener una medida de vigilancia comparable entre países, es crucial normalizar por el tamaño poblacional. El proceso se realiza en dos fases:
Integración de la Infraestructura de Vigilancia:
Se accede a los metadatos de las estaciones de la Agencia Europea de
Medio Ambiente (EEA) a través del paquete EEAaq, obteniendo el número de
estaciones activas por país (n_estaciones_activas), que es
una medida de la infraestructura de monitorización.
Cálculo de Métricas Normalizadas: Se unen los datos de población (Población_Eurostat_GIND) a las métricas de vigilancia. Finalmente, se crean las dos variables principales:
Estaciones por millón de habitantes
(estaciones_por_millon).
Observaciones por millón de habitantes
(Log-transformadas) (obs_por_millon_log),
siendo esta última la variable predictora clave (X) en el modelo de
regresión.
El dataframe resultante, df_vigilancia_tfr, contendrá
las métricas robustas de TFR y Vigilancia, listas para el análisis
estadístico y la visualización.
# Obtener metadatos de estaciones de la EEA (dataframe interno de EEAaq)
vigilancia_infraestructura <- EEAaq_get_dataframe("stations") %>%
clean_names() %>%
mutate(
pais = recode_pais(country)
) %>%
# Contar estaciones únicas (infraestructura) por país
group_by(pais) %>%
summarise(
n_estaciones_activas = n_distinct(air_quality_station_eo_i_code),
.groups = "drop"
)
# Carga de Datos de Población Reales (Usando el CSV de Eurostat DEMO_GIND)
poblacion_raw <- read_delim(
"INPUT/DATA/Poblacion_Eurostat_GIND.csv",
delim = ",", escape_double = FALSE, trim_ws = TRUE
) %>%
clean_names()
# Transformación de los datos de población:
poblacion_data <- poblacion_raw %>%
# Filtramos por el año central de nuestro análisis
filter(time_period == 2020) %>%
# Seleccionamos y transformamos las columnas clave
transmute(
country_name_raw = geo,
poblacion_millones = as.numeric(obs_value) / 1000000
) %>%
# Homogeneizamos el nombre del país para el join
mutate(pais = recode_pais(country_name_raw)) %>%
select(pais, poblacion_millones) %>%
filter(!is.na(poblacion_millones))
# Unión y Cálculo de Métricas Normalizadas
df_vigilancia_tfr <- resumen_aire_fert_pais %>%
left_join(vigilancia_infraestructura, by = "pais") %>%
left_join(poblacion_data, by = "pais") %>%
# Eliminar filas donde el denominador o numerador sea NA/cero
filter(
poblacion_millones > 0,
!is.na(total_obs_aire)
) %>%
mutate(
estaciones_por_millon = n_estaciones_activas / poblacion_millones,
# Cálculo de la variable clave: la función log1p maneja el log(1+0) = 0 sin error.
obs_por_millon_log = log1p(total_obs_aire / poblacion_millones)
) %>%
# Para solo conservar filas con valores finitos
filter(is.finite(tfr_media), is.finite(obs_por_millon_log))
Se genera un gráfico de barras que visualiza la métrica de
Infraestructura de Vigilancia normalizada
(estaciones_por_millon). Para facilitar la visualización de
la hipótesis, los países se ordenan por su TFR media, y
el color de las barras se mapea a la TFR. Esto permite evaluar si una
mayor TFR se asocia con una mayor altura de barra.
df_ordenado <- df_vigilancia_tfr %>%
# Se crea un factor para ordenar el eje X por TFR_media ascendente
mutate(pais_ordenado = forcats::fct_reorder(pais, tfr_media))
ggplot(df_ordenado,
aes(x = pais_ordenado, y = estaciones_por_millon)) +
# Barras (geom_col), coloreadas por la TFR media
geom_col(aes(fill = tfr_media), stat = "identity") +
# Escala de color para representar la fertilidad
scale_fill_gradient(
low = "peachpuff",
high = "red",
space = "Lab",
name = "TFR media"
) +
labs(
title = "Asociación entre Infraestructura de Vigilancia (EEAaq) y Fertilidad",
subtitle = "Países ordenados por TFR media. Altura = Estaciones de monitorización por millón de habitantes.",
x = NULL,
y = "Nº de Estaciones Activas (por millón de hab.)"
) +
scale_y_continuous(expand = expansion(mult = c(0, .1)),
labels = scales::comma) +
theme_classic() +
theme(
axis.text.x = element_text(angle = 60, vjust = 1, hjust = 1, size = 8),
plot.title = element_text(face = "bold", hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5)
)
Resultados del gráfico de barras El gráfico está
ordenado de izquierda a derecha por la fertilidad (TFR) de los países.
Los países con la TFR más baja están a la izquierda y los que tienen
la TFR más alta están a la derecha.
Si existiera una asociación positiva (mayor vigilancia = mayor fertilidad), esperaríamos ver un patrón en el que las barras (altura) se hicieran progresivamente más altas a medida que se avanza de izquierda a derecha.
En la gráfica observamos que no hay un patrón claro en la altura de las barras a lo largo del eje x, lo que significa que no existe una relación entre la fertilidad con la mayor vigilancia.
Ejemplo: Países como Lituania y Serbia muestran barras extremadamente altas (muy alta vigilancia por habitante), pero su TFR (color) no es la más alta de Europa.
Refutación de la Hipótesis Inicial: El gráfico sugiere que la hipótesis de que “una mayor inversión en vigilancia se asocia con niveles de fertilidad ligeramente superiores” es probablemente falsa.
El diagrama de dispersión analiza la relación entre la
Frecuencia de Reporte normalizada
(obs_por_millon_log) y la TFR. Se incluye
una recta de regresión lineal (OLS) para evaluar visualmente la
tendencia y bandas de confianza para la incertidumbre.
df_etiquetas <- df_vigilancia_tfr %>%
# Etiquetar países con valores extremos para control visual de outliers
mutate(
Etiqueta_pais = ifelse(
tfr_media < 1.35 | tfr_media > 1.8 | obs_por_millon_log > 10,
pais,
""
)
)
ggplot(df_etiquetas, aes(x = tfr_media, y = obs_por_millon_log)) +
# Puntos con transparencia y tamaño fijo
geom_point(aes(color = tfr_media), size = 3, alpha = 0.7) +
# Línea de regresión lineal (OLS) para visualizar la asociación
geom_smooth(method = "lm", se = TRUE, color = "#4682B4", linetype = "dashed") +
# Etiquetado para identificar países clave
geom_text_repel(
aes(label = Etiqueta_pais),
box.padding = 0.5,
point.padding = 0.5,
max.overlaps = Inf,
segment.color = 'grey50',
size = 3
) +
scale_color_gradient(low = "#FFD700", high = "#B8860B", name = "TFR") +
labs(
title = "Frecuencia de Vigilancia (Normalizada) vs. Fertilidad Media",
subtitle = "Log(Obs. de Aire/Millón de Hab.) en función de la TFR media",
x = "Tasa de Fecundidad Total (TFR) Media",
y = "Frecuencia de Vigilancia (Log de Obs. por Millón de Habitantes)"
) +
theme_minimal(base_size = 14) +
theme(plot.title = element_text(face = "bold"))
Resultados del gráfico de dispersión:
El gráfico de dispersión muestra cómo se relacionan dos variables al colocar cada país como un punto en un plano.
Este gráfico evalúa la relación entre la Frecuencia de Reporte de Calidad del Aire (cuántas mediciones se envían, ajustado por población en el Eje Y) y la Tasa de Fecundidad Total (TFR) (en el Eje X).
Eje X: Cuanto más a la derecha está un país, mayor es su fertilidad media (TFR).
Eje Y: Cuanto más arriba está un país, mayor es su frecuencia de reporte de datos de aire por habitante (más datos envían).
Los puntos están distribuidos de forma caótica en todo el gráfico. No forman una línea o una curva clara que indique una relación.
La Línea de Tendencia (Regresión) que atraviesa la gráfica representa la tendencia media de la relación. Esta línea es casi perfectamente horizontal, lo que significa que el valor de la TFR (movernos a la derecha) no hace que la frecuencia de vigilancia suba ni baje (el punto Y se queda en el mismo nivel).Por lo tanto no existe una relación entre ambos.
Ejemplo: Hay países extremos, especialmente en la vigilancia, como España, Serbia, Eslovaquia y Alemania, que tienen niveles de vigilancia muy altos (puntos muy altos en el eje Y), pero sus TFRs son promedio o bajas.
Refutación de la Hipótesis Inicial: El gráfico sugiere que la hipótesis de que “una mayor vigilancia se asocia con niveles de fertilidad superiores” es probablemente falsa.
Este apartado tiene como objetivo someter a prueba nuestra hipótesis central de que la frecuencia de la vigilancia ambiental se asocia con la fertilidad. Para ello, se emplea el Modelo de Mínimos Cuadrados Ordinarios (OLS).
Se utiliza el método de Errores Estándar Robustos (Huber-White, tipo HC1), que ajusta la varianza de los errores para obtener coeficientes y valores p más fiables, incluso bajo la presencia de heterocedasticidad.
La regresión se establece con la TFR media como variable dependiente (\(Y\)) y la variable Log(Obs. de Aire por Millón de Habitantes) (\(\log(1+X_{Normalizada})\)) como variable independiente o predictora.
# Filtro final del dataframe (Asegura que X e Y sean finitos)
datos_regresion <- df_vigilancia_tfr %>%
filter(is.finite(tfr_media), is.finite(obs_por_millon_log))
# Modelo OLS
modelo_final <- lm(tfr_media ~ obs_por_millon_log, data = datos_regresion)
resultados_robustez <- coeftest(
modelo_final,
vcov = vcovHC(modelo_final, type = "HC1")
)
# Tabulación de resultados
tabla_regresion_formato_simple <- tidy(resultados_robustez) %>%
rename(
T_Estadístico_Robusto = statistic,
Valor_P_Robusto = p.value
) %>%
mutate(
# Redondeamos las estimaciones y errores a 4 decimales
Estimación = round(estimate, 4),
Error_Estandar_Robusto = round(std.error, 4),
# Redondeamos el T-Estadístico a 3 decimales
T_Estadístico_Robusto = round(T_Estadístico_Robusto, 3),
# Mantenemos el P-value con más precisión para su interpretación
Valor_P_Robusto = round(Valor_P_Robusto, 6),
Significancia = case_when(
Valor_P_Robusto < 0.001 ~ "Altamente significativo",
Valor_P_Robusto < 0.01 ~ "Muy significativo",
Valor_P_Robusto < 0.05 ~ "Significativo",
TRUE ~ "No significativo"
)
) %>%
select(term, Estimación, Error_Estandar_Robusto, T_Estadístico_Robusto, Valor_P_Robusto, Significancia)
# Generación de la tabla
knitr::kable(
tabla_regresion_formato_simple,
caption = "Resultados de Regresión: TFR Media ~ Log(Obs. de Aire por Millón de Hab.) con Errores Estándar Robustos (HC1)",
# Alineación de las columnas (L=Left, R=Right)
align = c('l', 'r', 'r', 'r', 'r', 'c')
)
| term | Estimación | Error_Estandar_Robusto | T_Estadístico_Robusto | Valor_P_Robusto | Significancia |
|---|---|---|---|---|---|
| (Intercept) | 1.5593 | 0.0312 | 49.949 | 0.00000 | Altamente significativo |
| obs_por_millon_log | -0.0009 | 0.0029 | -0.320 | 0.74951 | No significativo |
Los resultados de la regresión lineal robusta confirman lo
visualizado en el análisis descriptivo. El coeficiente de la variable
Frecuencia de Vigilancia normalizada
(obs_por_millon_log) es \(-0.0009\), lo que indica una relación
prácticamente nula entre ambas variables. Más importante aún, el
Valor P Robusto (\(0.7495\)) es significativamente superior al
umbral de significancia de \(0.05\).
Por lo tanto, no existe evidencia estadística
significativa para concluir que la intensidad de la vigilancia
ambiental de la calidad del aire (ajustada por población) tenga algún
efecto o asociación lineal con la Tasa de Fecundidad Total (TFR) entre
los países de la muestra. La hipótesis inicial queda refutada en este
primer objetivo.
En esta segunda parte ampliamos el análisis pasando de la “vigilancia del aire” a la calidad del aire en sí, centrándonos en un contaminante clave: el dióxido de nitrógeno (NO₂). Este compuesto es un marcador típico de tráfico rodado y combustión urbana, y se ha vinculado con diversos efectos adversos para la salud, incluyendo riesgos durante el embarazo y potenciales impactos en la salud reproductiva.
Pregunta: ¿Existe una relación entre los niveles medios de NO₂ en cada país europeo y su fertilidad media? ¿De dónde proviene dicho NO₂?
Hipótesis: Esperamos observar una relación negativa, es decir, que países con mayor NO₂ medio deberían presentar, en promedio, niveles más bajos de fertilidad. Además, suponemos que la mayor parte del gas procederá de las estaciones de vigilancia de la calidad del aire de tráfico.
Como en el caso anterior, esta hipótesis es descriptiva, no causal; buscamos el signo de la asociación en los datos agregados.
Para esta sección combinamos dos fuentes principales:
OMS_Datos.xlsx)
NO2 (μg/m3)).pais
(por ejemplo, Turkey → Türkiye, Russian Federation →
Russia, Republic of Moldova → Moldova).fert_resumen_nombres)
tfr_media), ya
homogeneizada en la Parte 1 con la misma codificación de
pais.# Leer directamente desde la hoja principal
oms <- read_excel("INPUT/DATA/OMS_Datos.xlsx", sheet = "AAP_2022_city_v9")
# Solo países de la región europea de la OMS
oms_europa <- oms %>%
filter(`WHO Region` == "European Region")
# Variable 'pais' con nombres armonizados
oms_europa_limpio <- oms_europa %>%
mutate(pais = recode_pais(`WHO Country Name`))
Tras armonizar y unir ambas tablas mediante left_join(),
obtenemos un panel ciudad–país con valores de NO₂ y la fertilidad media
asociada a cada país.
A partir de éste, construimos un resumen por país con
las siguientes variables:
no2_media: media del NO₂ por país.no2_mediana: mediana del NO₂.n_ciudades: número de ciudades o localidades
monitorizadas.tfr_media: fertilidad media (Eurostat).Este resumen nos permite trabajar con una unidad clara (el país) y explorar la relación entre contaminación y fertilidad.
# JOIN: tabla OMS ciudad-país + resumen de fertilidad por país
oms_europa_con_fert <- oms_europa_limpio %>%
left_join(fert_resumen_nombres, by = "pais")
# Comprobar qué países de OMS no tienen fertilidad disponible
faltan_fert_oms <- oms_europa_limpio %>%
distinct(pais) %>%
anti_join(fert_resumen_nombres %>% distinct(pais), by = "pais")
# Resumen por país
pais_no2_fert <- oms_europa_con_fert %>%
group_by(pais) %>%
summarise(
no2_media = mean(`NO2 (μg/m3)`, na.rm = TRUE),
no2_mediana = median(`NO2 (μg/m3)`, na.rm = TRUE),
n_ciudades = n_distinct(`City or Locality`),
tfr_media = first(tfr_media), # viene del resumen de fertilidad (ya homog.)
.groups = "drop"
) %>%
filter(!is.na(no2_media), !is.na(tfr_media))
Para visualizar la relación NO₂–fertilidad utilizamos un gráfico de burbujas:
no2_media).tfr_media).n_ciudades).pais).Este enfoque es informativo porque combina: - diferencias en
contaminación,
- diferencias en fertilidad,
- y diferencias en la intensidad de monitorización entre países.
library(ggplot2)
library(ggrepel)
ggplot(
pais_no2_fert,
aes(
x = no2_media,
y = tfr_media,
size = n_ciudades
)
) +
geom_point(alpha = 0.7) +
geom_smooth(method = "lm", se = TRUE, linetype = "dashed") +
geom_text_repel(
aes(label = pais),
size = 3,
max.overlaps = 30
) +
scale_size_continuous(name = "Nº de ciudades\nmonitorizadas") +
labs(
title = "NO₂ medio vs fertilidad media por país europeo",
subtitle = "Tamaño del punto = nº de ciudades con datos de NO₂",
x = "NO₂ medio (µg/m³, OMS)",
y = "TFR media (Eurostat)"
) +
theme_minimal()
El gráfico revela una estructura altamente dispersa:
En otras palabras, no se aprecia evidencia de que mayores niveles medios de NO₂ estén sistemáticamente asociados con menores niveles de fertilidad en Europa.
Esto es coherente con la lectura de la Parte 1, pues el vínculo entre contaminación atmosférica y natalidad, de existir, parece ser débil a nivel agregado y, probablemente, mediado por múltiples factores (urbanización, edad materna, políticas familiares, estructura económica, densidad poblacional, etc.).
Aunque los efectos biológicos del NO₂ sobre la reproducción han sido documentados en estudios clínicos y epidemiológicos, estos pueden quedar enmascarados por la heterogeneidad interna de cada país y por la diferencia entre contaminación urbana y fertilidad nacional promedio.
En este tercer objetivo analizamos el papel de un contaminante global: el dióxido de carbono (CO₂).
A diferencia del NO₂, que refleja principalmente la contaminación urbana y la exposición directa de la población, el CO₂ es un gas de efecto invernadero cuya variación entre países está más ligada a su tamaño económico, estructura energética y nivel de industrialización.
Partimos de un fichero en formato JSON (CO2.json) que
contiene las emisiones anuales de CO₂ (en kilotoneladas) por país y por
año. A partir de este conjunto:
Se limpia y normaliza la información para construir una tabla
co2_limpio con las columnas:
pais (nombre del país armonizado),anio (año),co2_kt (emisiones totales de CO₂ en
kilotoneladas).Posteriormente, se agregan los datos por país para obtener el resumen
co2_resumen_pais, que incluye:
co2_kt_media: emisiones medias anuales de CO₂,co2_kt_total: emisiones acumuladas,n_anios_co2,
anio_min_co2, anio_max_co2).Finalmente, se realiza un full_join con
fert_resumen_nombres, de modo que
co2_fert_resumen_pais contiene, para cada país, las
emisiones medias de CO₂ y la TFR media en el mismo periodo de
referencia.
Este dataset combinado es la base para los gráficos y análisis de este objetivo.
# Leemos el JSON como Dataframe, no se por qué pero daba errores sino
dioxidocarbono_df <- jsonlite::fromJSON(
"INPUT/DATA/CO2.json",
simplifyDataFrame = TRUE # lo aplana a data.frame directamente
) %>%
as_tibble() %>%
clean_names()
#TABLA co2_limpio (país-año)
co2_limpio <- dioxidocarbono_df %>%
transmute(
pais = recode_pais(country_name),
anio = as.integer(year),
co2_kt = as.numeric(co2_emissions_kt)
) %>%
group_by(pais, anio) %>%
summarise(
co2_kt = sum(co2_kt, na.rm = TRUE),
.groups = "drop"
)
#PANEL CO2 + FERTILIDAD (país–año)
co2_fert_panel <- co2_limpio %>%
inner_join(fert_paises, by = c("pais", "anio"))
# RESUMEN POR PAÍS
co2_resumen_pais <- co2_limpio %>%
group_by(pais) %>%
summarise(
n_anios_co2 = n_distinct(anio),
anio_min_co2 = min(anio, na.rm = TRUE),
anio_max_co2 = max(anio, na.rm = TRUE),
co2_kt_media = mean(co2_kt, na.rm = TRUE),
co2_kt_total = sum(co2_kt, na.rm = TRUE),
.groups = "drop"
)
co2_fert_resumen_pais <- co2_resumen_pais %>%
full_join(fert_resumen_nombres, by = "pais") %>%
arrange(pais)
El análisis se estructura en dos pasos complementarios:
Gráfico de ranking tipo “lollipop” (Gráfico 3.1)
co2_kt_media).tfr_media): valores más altos se muestran con puntos más
grandes y colores más intensos.Este gráfico permite visualizar si los grandes emisores tienden a concentrarse en niveles de fertilidad sistemáticamente distintos del resto.
co2_lolli <- co2_fert_resumen_pais %>%
filter(!is.na(co2_kt_media),
!is.na(tfr_media))
ggplot(
co2_lolli,
aes(
x = co2_kt_media,
y = fct_reorder(pais, co2_kt_media)
)
) +
# palito
geom_segment(
aes(
x = 0,
xend = co2_kt_media,
y = fct_reorder(pais, co2_kt_media),
yend = fct_reorder(pais, co2_kt_media)
),
linewidth = 0.6,
alpha = 0.6
) +
# punto, coloreado por TFR
geom_point(
aes(
color = tfr_media,
size = tfr_media
),
alpha = 0.9
) +
scale_size_continuous(name = "TFR media") +
scale_color_viridis_c(name = "TFR media", option = "C") +
labs(
title = "Ranking de emisiones medias de CO2 y fertilidad en Europa",
subtitle = "Línea = emisiones medias de CO2 (kt) | Color/tamaño = TFR media",
x = "CO2 medio (kt, total país)",
y = NULL
) +
theme_minimal()
Gráfico animado CO₂–TFR por año (Gráfico 3.2)
Cada fotograma muestra un diagrama de dispersión entre
co2_kt y tfr para un año concreto.
Se ajusta una recta de regresión lineal por año, con su banda de confianza.
En la esquina de la animación se añaden el número de países incluidos y los coeficientes estimados (pendiente y R²).
Esta animación permite ver si la relación CO₂–TFR cambia con el tiempo y si, en algún periodo concreto, aparece una tendencia clara (positiva o negativa).
co2_fert_anim <- co2_fert_panel %>%
filter(!is.na(co2_kt),
!is.na(tfr))
reg_stats <- co2_fert_anim %>%
group_by(anio) %>%
summarise(
n = n(),
beta = coef(lm(tfr ~ co2_kt))[2],
r2 = summary(lm(tfr ~ co2_kt))$r.squared,
.groups = "drop"
)
library(gganimate)
p_anim <- ggplot(
co2_fert_anim,
aes(
x = co2_kt,
y = tfr
)
) +
# puntos por país
geom_point(
aes(color = pais),
alpha = 0.7,
size = 2,
show.legend = FALSE
) +
# nombres de algunos países
ggrepel::geom_text_repel(
data = ~ dplyr::filter(
.x,
co2_kt == max(co2_kt) | tfr == max(tfr)
),
aes(label = pais),
size = 3,
max.overlaps = 30,
show.legend = FALSE
) +
# recta de regresión por año
geom_smooth(
method = "lm",
se = TRUE,
linetype = "dashed",
color = "deeppink"
) +
# texto con stats por año (beta, R², n)
geom_text(
data = reg_stats,
aes(
x = -Inf,
y = Inf,
label = sprintf("Beta = %.3f R2 = %.2f n = %d", beta, r2, n)
),
hjust = -0.05,
vjust = 1.2,
size = 3.2,
inherit.aes = FALSE
) +
scale_x_continuous(labels = scales::comma) +
labs(
title = "Relación entre emisiones de CO₂ y fertilidad en Europa",
subtitle = "Año: {frame_time}",
x = "CO2 total del país (kt)",
y = "Tasa global de fecundidad (TFR)"
) +
theme_minimal(base_size = 12) +
theme(
panel.grid.minor = element_blank(),
plot.title = element_text(face = "bold")
) +
transition_time(anio) +
ease_aes("linear")
# Ver la animación en el viewer
anim <- animate(
p_anim,
nframes = 150,
fps = 10,
renderer = gifski_renderer()
)
anim
El gráfico de “lollipop” muestra que:
Los países con mayores emisiones medias de CO₂ (por ejemplo, economías más grandes o con un mix energético intensivo en combustibles fósiles) no presentan niveles de fertilidad claramente diferenciados del resto.
Entre los países de la parte alta del ranking observamos TFR medias en un rango relativamente estrecho (en torno a 1.3–1.7 hijos por mujer), similares a las del resto de Europa.
Algunos países con emisiones muy bajas (como Malta o Albania) tampoco destacan por una fertilidad especialmente alta; al contrario, se sitúan en la parte baja o media del rango de TFR.
En conjunto, el ranking sugiere que no existe un patrón monotónico evidente del tipo “a más CO₂, menos (o más) fertilidad”. La posición en el ranking de emisiones parece estar explicada sobre todo por factores estructurales (tamaño económico, industria, energía), mientras que la fertilidad se mueve en un margen relativamente estrecho sin alinearse claramente con esas diferencias.
La animación año a año refuerza esta impresión:
En cada fotograma, los puntos (países) se distribuyen de forma bastante difusa sobre el plano CO₂–TFR, sin que se forme una nube claramente ascendente o descendente.
Las rectas de regresión que se ajustan por año suelen tener pendientes pequeñas y, visualmente, la banda de confianza es amplia y abarca valores cercanos a una pendiente nula.
Los coeficientes de determinación (R²) que se muestran en la animación son bajos en la mayoría de años, lo que indica que las emisiones de CO₂ explican sólo una fracción muy limitada de la variación en fertilidad entre países.
Tampoco se aprecia un cambio cualitativo de la relación a lo largo del tiempo: no hay un periodo donde la asociación se vuelva claramente más fuerte o cambie de signo de forma clara.
En términos prácticos, la lectura estadística es que, en los datos agregados país–año, las emisiones totales de CO₂ no guardan una relación robusta con la TFR:
Estos resultados son coherentes con la naturaleza del indicador:
El CO₂ es un contaminante global, cuyo volumen anual refleja principalmente tamaño económico, estructura productiva e intensidad energética, más que la exposición individual de la población a contaminantes locales.
Los mecanismos biológicos que podrían afectar a la fertilidad suelen estar más vinculados a exposiciones locales (NO₂, PM₂.₅, ozono, etc.) que a las emisiones totales de CO₂ a escala nacional.
Además, la fertilidad está fuertemente condicionada por factores demográficos y socioeconómicos (edad a la maternidad, mercado laboral, políticas de conciliación, normas culturales), que pueden enmascarar cualquier efecto asociado a un indicador tan agregado como las emisiones de CO₂.
Por tanto, el tercer objetivo confirma la idea general de los
anteriores:
cuando miramos a nivel país, con indicadores agregados, la relación
entre contaminación (o emisiones) y fertilidad en Europa parece ser,
como mínimo, muy débil y fuertemente confundida por otras dimensiones
estructurales.
En este último objetivo profundizamos en un contaminante concreto, el material particulado fino (PM₂.₅), que se ha asociado con efectos adversos sobre la salud reproductiva, el embarazo y la mortalidad perinatal. A diferencia de los objetivos anteriores, centrados en la intensidad global de la vigilancia o en contaminantes específicos como el NO₂ o el CO₂, aquí nos interesa qué peso tiene el PM₂.₅ dentro del esfuerzo total de monitorización de la calidad del aire en cada país. Este indicador mide el tamaño de las partículas en el aire, tomando en cuenta aquellas de 2,5 micrómetros o menos; cuanto más pequeñas son estas partículas, más profundo llegan a los pulmones. Es claro que personas con patologías respiratorias sufrirán más la presencia de un PM₂.₅ alto, aunque a largo plazo toda la población se acaba viendo afectada por ellas.
La lógica es la siguiente: incluso si dos países tienen un volumen similar de observaciones de calidad del aire, pueden diferir en el énfasis que ponen sobre determinados contaminantes. Un país que dedica una mayor proporción de su vigilancia al PM₂.₅ estaría, en principio, más orientado a monitorizar riesgos finos para la salud cardiovascular y respiratoria, con posibles implicaciones para la salud reproductiva y, de forma indirecta, para la planificación familiar.
Pregunta: ¿Existe una relación entre el peso relativo del PM₂.₅ en la vigilancia del aire y la fertilidad media (TFR) de los países europeos?
Hipótesis: Si el PM₂.₅ es un marcador relevante de riesgos ambientales percibidos o efectivos, cabría esperar que los países que dedican una fracción mayor de sus observaciones a este contaminante presenten entornos más saludables o más vigilados, lo que podría asociarse con una fertilidad algo más elevada. De forma descriptiva, planteamos la hipótesis de que una mayor proporción de observaciones de PM₂.₅ se asocia con una TFR media más alta, aunque sin asumir causalidad.
En este objetivo analizamos el lugar que ocupa el contaminante PM₂.₅ dentro de la monitorización de calidad del aire en Europa.
Partimos del fichero de registros de calidad del aire
(aire), que contiene observaciones por país, año y tipo de
contaminante. A partir de este conjunto:
pais), al igual que
en los objetivos anteriores.anio).es_pm25, que toma valor
TRUE cuando el contaminante corresponde a PM₂.₅ (incluyendo
variantes como "PM2.5", "PM25",
"PM2p5").Con esta base construimos el resumen por país
pm25_share_pais, que contiene:
n_obs_total: número total de observaciones,n_obs_pm25: observaciones PM₂.₅,prop_pm25: proporción de observaciones dedicadas a
PM₂.₅,n_anios: número de años con observaciones.Después unimos este resumen con fert_resumen_nombres
para obtener pm25_share_tfr, que contiene tanto la
proporción de PM₂.₅ como la fertilidad media (tfr_media)
por país.
# Metadatos de estaciones EEA (dataframe interno)
stations_eea <- EEAaq_get_dataframe("stations") %>%
clean_names() %>%
mutate(
pais_raw = str_trim(country),
pais = recode_pais(country)
)
# Renombramos columna problemática
stations_meta <- stations_eea %>%
rename(air_quality_station_eoi_code = air_quality_station_eo_i_code) %>%
select(
air_quality_station_eoi_code,
pais,
air_quality_station_area,
air_quality_station_type
)
# CÁLCULO DE PROPORCIÓN DE PM2.5 POR PAÍS
pm25_share_pais <- aire %>%
mutate(
pais = recode_pais(country),
anio = as.integer(year),
es_pm25 = air_pollutant %in% c("PM2.5", "PM25", "PM2p5")
) %>%
group_by(pais) %>%
summarise(
n_obs_total = n(),
n_obs_pm25 = sum(es_pm25, na.rm = TRUE),
prop_pm25 = n_obs_pm25 / n_obs_total,
n_anios = n_distinct(anio),
.groups = "drop"
) %>%
arrange(desc(prop_pm25))
#UNIÓN PM2.5 + TFR
pm25_share_tfr <- pm25_share_pais %>%
left_join(fert_resumen_nombres, by = "pais") %>%
filter(!is.na(tfr_media), !is.na(prop_pm25))
Para examinar cómo se relacionan el peso relativo de PM₂.₅ y la fertilidad media, utilizamos un gráfico circular de barras radiales. Esta visualización permite comparar simultáneamente ambos indicadores de manera intuitiva. El planteamiento es el siguiente:
prop_pm25, es decir, la proporción de todas las
observaciones de calidad del aire que pertenecen a PM₂.₅ en ese
país.tfr_media (tasa global de fecundidad media).Ordenamos los países de forma descendente por
prop_pm25.
Después, convertimos pais en un factor con ese orden.
Esto asegura que, al pasar a coordenadas polares, los países aparezcan
ordenados alrededor del círculo según su peso relativo
de PM₂.₅.
Creamos un gráfico con geom_col() en
coordenadas cartesianas.
Transformamos el gráfico mediante
coord_polar(), convirtiendo las barras en
segmentos radiales que parten del centro.
tfr_media facilita
detectar patrones visuales:# Ordenamos países por prop_pm25 y preparamos factor
pm25_circ <- pm25_share_tfr %>%
arrange(desc(prop_pm25)) %>%
mutate(
pais = factor(pais, levels = pais),
label_pm = scales::percent(prop_pm25, accuracy = 1)
)
ggplot(
pm25_circ,
aes(
x = pais,
y = prop_pm25,
fill = tfr_media
)
) +
# barras radiales
geom_col(color = "white", width = 0.9, alpha = 0.9) +
# pasamos a coordenadas polares
coord_polar(start = -pi/2) +
# etiquetas con % PM2.5
geom_text(
aes(label = label_pm),
position = position_stack(vjust = 1.02),
size = 2.5,
show.legend = FALSE
) +
scale_y_continuous(labels = scales::percent_format(accuracy = 10)) +
labs(
title = "Peso relativo de PM2.5 en la vigilancia del aire por país",
subtitle = "Longitud de la barra = proporción de observaciones de PM2.5\nColor = TFR media",
x = NULL,
y = NULL,
fill = "TFR media"
) +
theme_minimal() +
theme(
axis.text.x = element_text(size = 7, angle = 0, vjust = 0.5),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
plot.title = element_text(face = "bold", hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5),
legend.position = "right"
)
El gráfico circular revela que el peso relativo del PM₂.₅ en la vigilancia de la calidad del aire es, en términos generales, bajo y heterogéneo entre países. La mayoría sitúa entre un 5 % y un 10 % de sus observaciones en PM₂.₅, mientras que solo un grupo reducido (entre ellos algunos países del norte o del entorno caucásico) supera claramente ese umbral y alcanza valores en torno al 12–16 %. En el extremo inferior aparecen varios países con barras muy cortas, señal de que el PM₂.₅ representa únicamente una fracción marginal de su registro total.
Al observar la escala de color, que codifica la
tfr_media, no emerge un gradiente coherente que acompañe la
longitud de las barras. Entre los países con mayor
prop_pm25 no destacan ni valores particularmente
altos ni particularmente bajos de fertilidad: sus tasas se concentran en
la zona intermedia del rango europeo. De forma
simétrica, entre los países cuyo peso relativo del PM₂.₅ es más reducido
encontramos tanto TFR comparativamente altas como
TFR bajas.
En conjunto, la visualización no sugiere la existencia de un patrón monotónico claro del tipo «a mayor peso relativo de PM₂.₅, mayor (o menor) fertilidad». La importancia que cada país otorga a la monitorización del PM₂.₅ parece estar determinada, más bien, por criterios técnicos, regulatorios o institucionales propios de sus sistemas de vigilancia, y no por diferencias sistemáticas en comportamiento demográfico.
Así, del mismo modo que en los análisis previos, la evidencia descriptiva apunta a que la relación entre el peso relativo del PM₂.₅ en la monitorización del aire y la fertilidad media es débil y queda probablemente absorbida por otros factores económicos, sociales y demográficos que este indicador agregado no capta.
Los análisis realizados indican que, a escala de país, la relación entre vigilancia de la calidad del aire, niveles de contaminación y fertilidad (TFR) en Europa es, en el mejor de los casos, débil y poco sistemática. El volumen total de observaciones de calidad del aire no muestra una asociación clara con la TFR media: los países que vigilan más no presentan, en promedio, una fertilidad ni claramente más alta ni más baja que los que vigilan menos. Los tests de correlación refuerzan esta idea, con coeficientes muy pequeños y no significativos.
Algo similar ocurre cuando se pasa de la vigilancia a la contaminación efectiva. Ni los niveles medios de NO₂ ni las emisiones de CO₂ —interpretadas como un indicador agregado de tamaño económico e intensidad energética— permiten ordenar a los países europeos según su nivel de fertilidad. Los diagramas de dispersión y las rectas de regresión muestran nubes muy dispersas, pendientes próximas a cero y R² bajos, lo que indica que estas variables ambientales explican solo una fracción mínima de la variación en TFR entre países.
El análisis del peso relativo del PM₂.₅ en la vigilancia tampoco revela patrones robustos: algunos países otorgan a este contaminante una proporción relativamente alta de sus observaciones, mientras que otros apenas lo monitorizan, pero en ambos grupos aparecen TFR bajas, medias y algo más altas. En definitiva, dedicar una mayor parte del esfuerzo de vigilancia al PM₂.₅ no se traduce en niveles de fertilidad claramente diferenciados.
En conjunto, los resultados apuntan a que la variación en la fertilidad europea está dominada por factores demográficos, socioeconómicos e institucionales (estructura de edades, mercado laboral, políticas de conciliación, normas culturales, gasto social, etc.) que este marco descriptivo no modeliza de forma directa. Las variables ambientales consideradas —vigilancia, NO₂, CO₂, peso del PM₂.₅— parecen jugar, a este nivel de agregación, un papel secundario frente a esos determinantes estructurales.
Estas conclusiones deben interpretarse con cautela: se trata de un estudio ecológico y descriptivo, basado en datos agregados por país, sin control exhaustivo por posibles factores de confusión y con indicadores ambientales relativamente gruesos (medias nacionales, totales anuales). La evidencia disponible no niega que la calidad del aire afecte a la salud reproductiva, pero sí sugiere que sus efectos sobre la fecundidad observada a nivel de país son difíciles de detectar con este tipo de datos. En este sentido, el trabajo funciona como un punto de partida exploratorio que señala la necesidad de estudios con mayor resolución espacial, datos individuales y diseños longitudinales o cuasi experimentales para comprender con más precisión los vínculos entre contaminación atmosférica y fertilidad.
Eurostat. (s. f.). Fertility statistics (TFR by country and year). Oficina de Estadística de la Unión Europea.
Air Quality e-Reporting (AQ e-Reporting). (2022, August 5). https://www.eea.europa.eu/en/datahub/datahubitem-view/3b390c9c-f321-490a-b25a-ae93b2ed80c1
Emisiones globales de CO2. (2025, August 18). https://data.unesco.org/explore/dataset/co2001/information/?flg=es-es
World Health Organization. (2022). Ambient Air Pollution Database (AAP 2022). WHO, Department of Environment, Climate Change and Health.
Carré, J., Gatimel, N., Moreau, J., Parinaud, J., & Léandri, R. (2017). Does air pollution play a role in infertility? A systematic review. Environmental Health, 16(1), 82.
Landrigan, P. J., Fuller, R., Acosta, N. J. R., et al. (2018). The Lancet Commission on pollution and health. The Lancet, 391(10119), 462–512.
WHO. (2021). WHO global air quality guidelines: Particulate matter (PM₂.₅ and PM₁₀), ozone, nitrogen dioxide, sulfur dioxide and carbon monoxide. World Health Organization.